/*
 * SenseBarrier.java
 *
 * Created on August 3, 2005, 10:49 PM
 *
 * From "Multiprocessor Synchronization and Concurrent Data Structures",
 * by Maurice Herlihy and Nir Shavit.
 *
 * This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
 * http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png
 */

package barrier.senseBarrier;
import java.util.concurrent.atomic.AtomicInteger;

import barrier.Barrier;

/**
 * Sense-reversing barrier
 * @author Maurice Herlihy
 */
public class SenseBarrier implements Barrier {
  AtomicInteger count;     // how many threads have arrived
  int size;                // number of threads
  volatile boolean sense;  // object's sense
  ThreadLocal<Boolean> threadSense;
  
  /**
   * Constructor
   * @param n barrier width
   */
  public SenseBarrier(int n) {
    count = new AtomicInteger(n);
    size = n;
    sense = false;
    threadSense = new ThreadLocal<Boolean>() {
      @Override
      protected Boolean initialValue() { return !sense; };
    };
  }
  /**
   * Wait for threads to catch up.
   */
  @Override
  public void await() {
    boolean mySense = threadSense.get();
    int position = count.getAndDecrement();
    if (position == 1) { // I'm last
      count.set(this.size);     // reset counter
      sense = mySense;          // reverse sense
    } else {
      while (sense != mySense) {} // busy-wait
    }
    threadSense.set(!mySense);
  }
}
